home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-05-30 | 27.8 KB | 884 lines | [TEXT/ttxt] |
- // This may look like C code, but it is really -*- C++ -*-
- /*
- ************************************************************************
- *
- * Grayscale Image
- *
- * Verify the class image member functions and friends
- *
- * $Id: vimage.cc,v 2.0 1995/03/18 18:45:04 oleg Exp oleg $
- *
- ************************************************************************
- */
-
- #include "image.h"
- #include "std.h"
- #include <iostream.h>
- #include <minmax.h>
-
- static IMAGE Test_image(16,32,8); //(256,512,8);
-
-
- /*
- *----------------------------------------------------------------------
- * Testing primitive operations and inquires
- */
-
- static void test_primitive(void)
- {
- cout << "\n\nTest primitive image operations and inquires\n";
-
- IMAGE image(Test_image);
- cout << "\nInquires for the image like Test image";
- cout << "\nNo of rows " << image.q_nrows();
- cout << "\nNo of cols " << image.q_ncols();
- cout << "\nDepth " << image.q_depth();
- cout << "\nTotal no pixels " << image.q_npixels();
- cout << "\nName '" << image.q_name() << "'";
-
- cout << "\nThe following line is returned by image.info()\n";
- image.info();
-
- assert( image.q_npixels() == image.q_ncols() * image.q_nrows() );
-
- cout << "\nDone\n\n";
- }
-
- // Verify the rowcol class
- static void test_rowcol(void)
- {
- cout << "\n\nTest the rowcol class and operations on it\n";
-
- const int row_const = 5, col_const = 32005;
-
- {
- cout << "\tVerify constructing the rowcol object from two integers\n";
- rowcol pos1(row_const,col_const);
- assert( pos1.row() == row_const && pos1.col() == col_const );
- }
-
- {
- cout << "\tVerify assignment operations\n";
- rowcol pos1(row_const,col_const);
- rowcol pos2(-1,-1);
- assert( pos2.row() != row_const && pos2.col() != col_const );
- pos2 = pos1;
- assert( pos2.row() == row_const && pos2.col() == col_const );
- rowcol pos3(pos2);
- assert( pos3.row() == row_const && pos3.col() == col_const );
- pos3 = rowcol(col_const,row_const);
- assert( pos3.col() == row_const && pos3.row() == col_const );
- }
-
- {
- cout << "\tVerify comparisons\n";
- rowcol pos1(row_const,col_const);
- rowcol pos2(-1,-1);
- assert( !(pos2 == pos1) );
- pos2 = pos1;
- assert( pos2 == pos1 );
- assert( pos2 == rowcol(row_const,col_const) );
- rowcol pos4(row_const,0);
- assert( !(pos4 == pos1) );
- rowcol pos5(0,col_const);
- assert( !(pos5 == pos1) );
- }
-
- {
- cout << "\tVerify shifting and offsetting operations\n";
- rowcol pos1(row_const,col_const);
- rowcol pos2(pos1);
- assert( pos1 == pos2 );
-
- assert( (pos1-pos2) == rowcol(0,0) );
- assert( pos1 == pos2 );
- pos1 -= pos2;
- assert( pos1 == rowcol(0,0) );
- assert( pos2 == rowcol(row_const,col_const) );
-
- assert( (pos1+pos2) == pos2 );
- assert( !(pos1 == pos2) );
- pos1 += pos2;
- assert( pos1 == pos2 );
-
- assert( (pos1-rowcol(row_const,0)) == rowcol(0,col_const) );
- pos1 -= rowcol(row_const,0);
- assert( pos1 == rowcol(0,col_const) );
- pos1 += rowcol(0,1);
- assert( pos1 == rowcol(0,col_const+1) );
- pos2 -= pos1;
- assert( pos2 == rowcol(row_const,-1) );
- assert( (pos1+pos2) == rowcol(row_const,col_const) );
- pos1 += pos2;
- assert( pos1 == rowcol(row_const,col_const) );
- }
-
- {
- cout << "\tVerify scaling operations\n";
- rowcol pos1(4,5);
- rowcol pos2(pos1);
- pos1 *= 1;
- assert( pos1 == pos2 );
- pos1 *= 4;
- assert( pos1 == pos2 * 4 );
- assert( pos1 == pos2 << 2 );
- assert( pos1 >> 2 == pos2 );
- pos2 += pos2;
- pos2 += pos2;
- assert( pos1 == pos2 );
-
- }
-
- cout << "\nDone\n\n";
- }
-
- /*
- *----------------------------------------------------------------------
- * Testing reading/writing a pixel and pixel modifications
- */
-
-
- static void test_pixel_op()
- {
- const int pattern = 145;
- register int i,j;
-
- cout << "\n\nTest reading/writing pixels and pixel modifications\n";
-
- cout << "Writing zeros ...\n";
- for(i=0; i<Test_image.q_nrows(); i++)
- for(j=0; j<Test_image.q_ncols(); j++)
- Test_image(i,j) = 0;
-
- verify_pixel_value(Test_image,0);
- assert( Test_image == 0 );
-
- cout << "Writing a pattern 0x" << hex << pattern << dec << "...\n";
- for(i=0; i<Test_image.q_nrows(); i++)
- for(j=0; j<Test_image.q_ncols(); j++)
- Test_image(rowcol(i,j)) = pattern;
-
- verify_pixel_value(Test_image,pattern);
- assert( Test_image == pattern );
- assert( Test_image > 0 && Test_image >= pattern );
- assert( !(Test_image == 0) && Test_image != 0 );
- assert( Test_image > pattern-1 && Test_image >= pattern-1 );
- assert( Test_image < pattern+1 && Test_image <= pattern+1 );
- assert( Test_image <= pattern && !(Test_image < pattern) );
- assert( Test_image >= pattern && !(Test_image > pattern) );
-
- cout << "Inverting the image, the pattern has to turn to " <<
- hex << 0xff - pattern << "...\n";
- Test_image.invert();
- verify_pixel_value(Test_image,0xff - pattern);
-
- cout << "Clearing the image ...\n";
- Test_image.clear();
- verify_pixel_value(Test_image,0);
- assert( Test_image < pattern && Test_image <= pattern );
-
- const int test_val = 0x7e;
- cout << "Assigning the value " << hex << test_val
- << " to all the pixels...\n" << dec;
- Test_image = test_val;
- verify_pixel_value(Test_image,test_val);
-
- cout << "Adding three...\n";
- Test_image += 3;
- verify_pixel_value(Test_image,test_val+3);
- assure( Test_image > 0, "Negative pixel unexpected");
-
- cout << "Subtracting " << 2*test_val << "...\n";
- Test_image -= 2*test_val;
- verify_pixel_value(Test_image,test_val+3-2*test_val);
- assure( Test_image < 0, "Non-Negative pixel unexpected");
-
- cout << "Subtracting " << -2*test_val+3 << "...\n";
- Test_image -= -2*test_val+3;
- verify_pixel_value(Test_image,test_val);
-
- cout << "Set two lowest bits\n";
- Test_image |= 0x03;
- verify_pixel_value(Test_image,test_val | 0x03);
-
- cout << "Reset two lowest bits\n";
- Test_image &= 0xff - 0x03;
- verify_pixel_value(Test_image,test_val & (0xff - 0x03));
-
- cout << "Set the 2nd bit with XOR\n";
- Test_image ^= 0x02;
- verify_pixel_value(Test_image,test_val);
-
- cout << "Multiply by 2\n";
- Test_image *= 2;
- verify_pixel_value(Test_image,2*test_val);
-
- cout << "Multiply by 2 once more by shifting to the left\n";
- Test_image <<= 1;
- verify_pixel_value(Test_image,4*test_val);
-
- cout << "Divide by 4 by shifting to the right\n";
- Test_image >>= 2;
- verify_pixel_value(Test_image,test_val);
-
- cout << "If image >=0, then abs(image) should coincide with itself\n";
- assert( Test_image >= 0 );
- Test_image.abs();
- verify_pixel_value(Test_image,test_val);
-
- cout << "Assign image = -test_val and test image.abs()\n";
- Test_image -= 2*test_val;
- assert( Test_image < 0 );
- Test_image.abs();
- verify_pixel_value(Test_image,test_val);
-
- {
- cout << "Assign image = -test_val and test image.apply(abs)\n";
- Test_image -= 2*test_val;
- assert( Test_image < 0 );
- class AbsImage : public PixelPrimAction {
- void operation(GRAY& pixel) { pixel = abs((GRAY_SIGNED)pixel); }
- public: AbsImage(void) {}
- };
- Test_image.apply(AbsImage());
- verify_pixel_value(Test_image,test_val);
- }
-
- cout << "Assign image = -test_val and put down all negative pixels\n";
- Test_image -= 2*test_val;
- assert( Test_image < 0 );
- Test_image.clip_to_intensity_range();
- verify_pixel_value(Test_image,0);
-
- cout << "Assign image = max_val+test_val and clip to the intensity region\n";
- Test_image = test_val;
- Test_image.clip_to_intensity_range();
- verify_pixel_value(Test_image,test_val);
- Test_image += (1<<Test_image.q_depth())-1;
- Test_image.clip_to_intensity_range();
- verify_pixel_value(Test_image,(1<<Test_image.q_depth())-1);
-
- {
- cout << "Check to see that PixelAction are executed row-wise" << endl;
- class assign_pixels : public PixelAction {
- const card test_im_nrows, test_im_ncols;
- void operation(GRAY& pixel)
- {
- assert(nrows == test_im_nrows);
- assert(ncols == test_im_ncols);
- pixel = col + row*ncols;
- }
- public: assign_pixels(const IMAGE& im) :
- test_im_nrows(im.q_nrows()), test_im_ncols(im.q_ncols()) {}
- };
- Test_image.apply(assign_pixels(Test_image));
-
- class check_pixels : public PixelPrimAction {
- GRAY curr_value;
- void operation(GRAY& pixel) { assert(pixel == curr_value++); }
- public: check_pixels(void) : curr_value(0) {}
- };
- Test_image.apply(check_pixels());
- }
- cout << "\nDone\n\n";
- }
-
- static void test_image_op()
- {
- const int pattern = 144;
-
- cout << "\n\nTest binary image operations and comparisons\n";
- cout << "Pattern value being used " << pattern <<
- " (0x" << hex << pattern << dec << ")\n";
-
- cout << "Allocation with assignment\n";
- Test_image = pattern;
- IMAGE im2 = Test_image; im2 = Test_image;
- assure(Test_image == im2, "Non-identical images");
-
- cout << "Assignment of one image to the other\n";
- im2 += pattern;
- Test_image = im2;
- assure(Test_image==im2, "Non-identical images");
- verify_pixel_value(Test_image,2*pattern);
-
- cout << "Subtraction of two images\n";
- im2 = pattern;
- Test_image -= im2;
- assure(Test_image==im2, "Non-identical images");
- verify_pixel_value(Test_image,pattern);
- assert(Test_image == pattern);
-
- cout << "Addition of images\n";
- Test_image += im2;
- assure(!(Test_image==im2), "Identical images unexpected");
- verify_pixel_value(Test_image,2*pattern);
-
- #if 0
- cout << "Addition of images through add() function\n";
- add(Test_image,2,im2);
- assure(!(Test_image==im2), "Identical images unexpected");
- verify_pixel_value(Test_image,4*pattern);
-
- cout << "Subtraction of images through add() function\n";
- add(Test_image,-3,im2);
- assure(Test_image==im2, "Non-identical images");
- verify_pixel_value(Test_image,pattern);
-
- cout << "Double only one pixel,(5,6), and perform operations to triple it\n";
- Test_image(5,6) *= 2;
- Test_image += im2;
- add(Test_image,-3,im2);
- Test_image += Test_image;
- add(Test_image,3,im2);
- compare(Test_image,im2,"Image with one pixel different and original");
- #endif
-
- cout << "Subtracting the image from itself\n";
- Test_image -= Test_image;
- verify_pixel_value(Test_image,0);
-
- cout << "Set two lower bits\n";
- Test_image = pattern; im2 = 0x03;
- Test_image |= im2;
- verify_pixel_value(Test_image,pattern | 0x03);
-
- cout << "Reset two lowest bits\n";
- im2.invert();
- Test_image &= im2;
- verify_pixel_value(Test_image,pattern & (0xff - 0x03));
-
- cout << "Set the 2nd bit with XOR\n";
- im2 = 0x02;
- Test_image ^= im2;
- verify_pixel_value(Test_image,pattern | 0x02);
-
- cout << "OR with 0x13 followed by AND with 0x6d for non-uniform image\n";
- Test_image = pattern; Test_image(4,5) += 5;
- im2 = 0x13; Test_image |= im2; im2.invert(); Test_image &= im2;
- im2 = pattern; im2(4,5) += 5;
- im2 |= 0x13; im2 &= ~(0x13);
- assure(Test_image == im2,"Pixel-by-pixel and image-by-image produced"
- "different results");
-
- cout << "XORing the image with itself\n";
- Test_image ^= Test_image;
- verify_pixel_value(Test_image,0);
-
- #if 0
- cout << "Add two images through shift_clip_add\n";
- Test_image = pattern;
- Test_image.shift_clip_add(rowcol(0,0),1,Test_image);
- verify_pixel_value(Test_image,2*pattern);
- im2 = pattern;
- Test_image.shift_clip_add(rowcol(0,0),-2,im2);
- verify_pixel_value(Test_image,0);
-
- {
- cout << "Change a single pixel through shift_clip_add\n";
- Test_image = 2*pattern;
- im2 = pattern;
- rowcol rightbottom(Test_image.q_nrows()-1,Test_image.q_ncols()-1);
- Test_image(rightbottom) += pattern; // Increment a pixel
- assert( !(Test_image == 2*pattern) && !(Test_image != 2*pattern) );
- Test_image.shift_clip_add(rightbottom,-1,im2); // and decrement it back
- verify_pixel_value(Test_image,2*pattern); // in the other way
- assert( Test_image == 2*pattern );
-
- {
- Test_image(0,0) -= pattern;
- assert( !(Test_image == 2*pattern) && !(Test_image != 2*pattern) );
- rowcol pos = rightbottom * (-1);
- Test_image.shift_clip_add(pos,1,im2);
- // Test_image.shift_clip_add(rightbottom * (-1),1,im2);
- verify_pixel_value(Test_image,2*pattern);
- assert( Test_image == 2*pattern );
- }
- }
-
- {
- cout << "Change a bottom right quadrant through shift_clip_add\n";
- Test_image = 2*pattern;
- im2 = pattern;
- rowcol rightbottom(Test_image.q_nrows()-1,Test_image.q_ncols()-1);
- rowcol center(Test_image.q_nrows()/2,Test_image.q_ncols()/2);
- Test_image.rectangle(center,rightbottom) -= 2*pattern; // Decrement a block
- assert( !(Test_image == 2*pattern) && !(Test_image != 2*pattern) );
- Test_image.shift_clip_add(center,2,im2); // and increment it back
- verify_pixel_value(Test_image,2*pattern); // in the other way
- assert( Test_image == 2*pattern );
- }
-
- {
- cout << "Change a part of the image through shift_clip_add\n";
- Test_image = 3*pattern;
- rowcol pos1(4,5);
- rowcol pos2(Test_image.q_nrows()-2,Test_image.q_ncols()-3);
- IMAGE im3 = Test_image.rectangle(pos1,pos2);
- Test_image.rectangle(pos1,pos2) -= 3*pattern; // Decrement a block
- assert( !(Test_image == 3*pattern) && !(Test_image != 3*pattern) );
- assert( im3 == 3*pattern );
- Test_image.shift_clip_add(pos1,1,im3); // and increment it back
- verify_pixel_value(Test_image,3*pattern); // in the other way
- assert( Test_image == 3*pattern );
- }
- #endif
-
- cout << "\nDone\n\n";
- }
-
- /*
- *------------------------------------------------------------------------
- * Testing norm and scalar product calculations
- */
-
- static void test_scalar_product()
- {
- const int pattern = 145;
-
- cout << "\n\nTest the computation of the scalar product of two images\n";
- cout << "Pattern value being used " << pattern;
-
- int dim = (max(Test_image.q_nrows(),Test_image.q_ncols()) >> 1) << 1;
- IMAGE imt(dim,dim,8), ims(dim,dim,8);
-
- cout << "\nSquare image of size " << dim << " is being tested";
- cout << "\nTesting by making the Haar (+ - - +) function and checking\n"
- "its orthogonality with other Haar functions";
-
- // Make the Haar (+ - - +) function
- ims.square_of(dim/2,rowcol(0,0)) = pattern;
- ims.square_of(dim/2,rowcol(0,dim/2)) = -pattern;
- ims.square_of(dim/2,rowcol(dim/2,0)) = -pattern;
- ims.square_of(dim/2,rowcol(dim/2,dim/2)) = pattern;
- assert( ims != 0 && !(ims == 0) && !(ims == pattern) && !(ims != pattern) );
- assert( !(ims >= pattern) && ims >= -pattern && ims <= pattern );
- assert( !(ims > 0) && !(ims < 0) );
-
-
- cout << "\nsum over ims " << sum_over(ims.square_of(dim,rowcol(0,0)));
-
- imt = pattern;
- cout << "\n Scalar product with Haar (+ + + +) function is " << ims * imt;
-
- imt.square_of(dim/2,rowcol(0,0)) = -pattern;
- imt.square_of(dim/2,rowcol(0,dim/2)) = -pattern;
- imt.square_of(dim/2,rowcol(dim/2,0)) = pattern;
- imt.square_of(dim/2,rowcol(dim/2,dim/2)) = pattern;
- cout << "\n Scalar product with Haar (- - + +) function is " << imt * ims;
-
- imt.square_of(dim/2,rowcol(0,0)) = -pattern;
- imt.square_of(dim/2,rowcol(0,dim/2)) = pattern;
- imt.square_of(dim/2,rowcol(dim/2,0)) = -pattern;
- imt.square_of(dim/2,rowcol(dim/2,dim/2)) = pattern;
- cout << "\n Scalar product with Haar (- + - +) function is " << ims * imt;
-
- imt = ims;
- cout << "\n Scalar product with Haar (+ - - +) function is " << imt * ims;
- cout << "\n Theoretical value "
- << sqr(pattern * dim);
- assure( imt * ims == sqr(pattern * dim), "There is discrepancy!" );
-
- cout << "\nDone\n\n";
- }
-
- static void test_image_norms(void)
- {
- const int pattern = 154;
-
- cout << "\n\nTest image norm computations\n";
-
- Test_image.clear();
-
- cout << "\nInitializing the image with the pattern " << pattern << "...\n";
- Test_image = pattern;
-
- cout << "\tChecking out the 1. image norm, which should be "
- << pattern * (double)Test_image.q_npixels() << "\n";
- assert( Test_image.norm_1() == pattern * (double)Test_image.q_npixels() );
- cout << "\tChecking out the 2. image norm, which should be "
- << pattern * pattern * (double)Test_image.q_npixels() << "\n";
- assert( Test_image.norm_2_sqr() ==
- sqr(pattern) * (double)Test_image.q_npixels() );
- cout << "\tChecking out the 2. image norm is equal to the scalar product\n"
- "\t\tof the image with itself\n";
- assert( Test_image.norm_2_sqr() == Test_image * Test_image );
- cout << "\tChecking out the inf image norm is equal to the pattern itself\n";
- assert( Test_image.norm_inf() == pattern );
-
- cout << "\nInitializing the image with the pattern " << pattern <<
- "\n with a quater of it being set to " << -2*pattern << "\n";
- Test_image = pattern;
- int size = min(Test_image.q_ncols(),Test_image.q_nrows())/2;
- Test_image.square_of(size,rowcol(0,0)) = -2*pattern;
- assert( !(Test_image == pattern) && !(Test_image != pattern) );
- assert( Test_image <= pattern && Test_image >= -2*pattern );
- assert( !(Test_image > 0) && !(Test_image < 0) && Test_image != 0 );
-
- cout << "\tChecking out the 1. image norm\n";
- assert( Test_image.norm_1() == pattern * (double)Test_image.q_npixels()
- + pattern * size * size );
- {
- IMAGE im(Test_image);
- im = Test_image;
- im.abs();
- assert( im.norm_1() == Test_image.norm_1() );
- }
-
- cout << "\tChecking out the 2. image norm\n";
- assert( Test_image.norm_2_sqr() ==
- sqr(pattern) * (double)Test_image.q_npixels() +
- 3 * sqr(pattern) * sqr(size) );
- {
- IMAGE im(Test_image); IMAGE im1(im);
- im = pattern;
- im.square_of(size,rowcol(0,0)) = -1;
- im1 = im;
- class SqrImage : public PixelPrimAction {
- void operation(GRAY& pixel) { pixel = sqr((GRAY_SIGNED)pixel); }
- public: SqrImage(void) {}
- };
- im1.apply(SqrImage());
- assert( sum_over((Rectangle)im1) == im.norm_2_sqr() );
- }
- cout << "\tChecking out the 2. image norm is equal to the scalar product\n"
- "\t\tof the image with itself\n";
- assert( Test_image.norm_2_sqr() == Test_image * Test_image );
- cout << "\tChecking out the inf image norm\n";
- assert( Test_image.norm_inf() == 2*pattern );
-
- cout << "\nChecking out that the image is equal to itself\n"
- "(according to norms)\n";
- assert( norm_1(Test_image,Test_image) == 0 );
- assert( norm_2_sqr(Test_image,Test_image) == 0 );
- assert( norm_inf(Test_image,Test_image) == 0 );
-
- cout << "\nCheck the difference between the test images set as above"
- "\nand the image with the uniform pattern\n";
- IMAGE im1(Test_image);
- im1 = pattern;
-
- cout << "\tVerify the identity ||im1-im2|| = ||im2-im1||\n";
- assert( norm_1(Test_image,im1) == norm_1(im1,Test_image) );
- assert( norm_2_sqr(Test_image,im1) == norm_2_sqr(im1,Test_image) );
- assert( norm_inf(Test_image,im1) == norm_inf(im1,Test_image) );
-
- cout << "\tVerify the norm values\n";
- assert( norm_1(Test_image,im1) == 3 * pattern * sqr(size) );
- assert( norm_2_sqr(Test_image,im1) == sqr(3 * pattern) * sqr(size) );
- assert( norm_inf(Test_image,im1) == 3 * pattern );
-
- cout << "\nDone\n\n";
- }
-
- // Check out min/max finding operations
- static void test_image_extrema(void)
- {
- const int pattern = 154;
-
- cout << "\n\nTest finding extremum pixel values and image normalization\n";
-
- {
- cout << "\n\tExtrema of the zero image\n";
- Test_image.clear();
- Extrema extr(Test_image);
- assert( extr.min() == 0 && extr.max() == 0 );
- }
-
- {
- cout << "\tInitializing the image with the pattern " << pattern << "\n";
- Test_image = pattern;
- Extrema extr(Test_image);
- assert( extr.min() == pattern && extr.max() == pattern );
- }
-
- {
- cout << "\tSetting pixel (1,2) to 0\n";
- Test_image(1,2) = 0;
- Extrema extr(Test_image);
- assert( extr.min() == 0 && extr.max() == pattern &&
- extr.loc_min() == rowcol(1,2) );
- assert( Test_image >= extr.min() && Test_image <= extr.max() );
- }
-
- {
- cout << "\tSetting pixel (2,1) to 2*pattern = " << 2*pattern << "\n";
- Test_image(2,1) = 2*pattern;
- Extrema extr(Test_image);
- assert( extr.min() == 0 && extr.max() == 2*pattern &&
- extr.loc_min() == rowcol(1,2) && extr.loc_max() == rowcol(2,1) );
- assert( Test_image >= extr.min() && Test_image <= extr.max() );
- }
-
- {
- cout << "\tOffsetting by " << pattern << "\n";
- Test_image -= pattern;
- Extrema extr(Test_image);
- assert( extr.min() == -pattern && extr.max() == pattern &&
- extr.loc_min() == rowcol(1,2) && extr.loc_max() == rowcol(2,1) );
- assert( Test_image >= extr.min() && Test_image <= extr.max() );
- }
-
- {
- cout << "\tOffsetting by " << 2*pattern << "\n";
- Test_image -= 2*pattern;
- Extrema extr(Test_image);
- assert( extr.min() == -3*pattern && extr.max() == -pattern &&
- extr.loc_min() == rowcol(1,2) && extr.loc_max() == rowcol(2,1) );
- assert( Test_image >= extr.min() && Test_image <= extr.max() );
- }
-
- cout << "\tNormalization ... \n";
- Test_image = pattern;
- Test_image.square_of(4,rowcol(2,1)) = -3*pattern;
- Test_image.normalize_for_display();
- Extrema extr(Test_image);
- assert( extr.min() == 0 && extr.max() >= (1<<Test_image.q_depth())-2 );
- assert( Test_image >= extr.min() && Test_image <= extr.max() );
-
- cout << "\nDone\n\n";
-
- }
-
- // Test the histogram equalization
- static void test_equalization(void)
- {
- cout << "\n\nTest the histogram equalization\n";
-
- {
- cout << "\tTest equalizing 16x16x8 full-gray scale image\n";
- IMAGE full_gray(16,16,8);
- register int i,j;
- for(i=0; i<16; i++)
- for(j=0; j<16; j++)
- full_gray(i,j) = (i<<4) | j;
- Extrema full_gray_extr(full_gray);
- assert( full_gray_extr.min() == 0 && full_gray_extr.max() == 255 );
-
- full_gray.equalize(128);
- // After the equalization, the
- // image should have (almost) the
- // same span but have only even
- // pixel values
- Extrema full_gray_extr_eq(full_gray);
- assert( full_gray_extr_eq.min() == 0 && full_gray_extr_eq.max() == 254 );
- for(i=0; i<16; i++)
- for(j=0; j<16; j++)
- assert( (full_gray(i,j) & 1) == 0 );
- }
-
- {
- cout << "\tAn image with a flat histogram should stay this way\n";
- IMAGE test_im(16,16,8);
- test_im.rectangle(rowcol(0,0),rowcol(15,3)) = 0;
- test_im.rectangle(rowcol(0,4),rowcol(15,7)) = 80;
- test_im.rectangle(rowcol(0,8),rowcol(15,11)) = 160;
- test_im.rectangle(rowcol(0,12),rowcol(15,15)) = 255;
-
- test_im.equalize(128);
-
- IMAGE test_im_ethalon(test_im);
- test_im_ethalon.rectangle(rowcol(0,0),rowcol(15,3)) = 31;
- test_im_ethalon.rectangle(rowcol(0,4),rowcol(15,7)) = 94;
- test_im_ethalon.rectangle(rowcol(0,8),rowcol(15,11)) = 158;
- test_im_ethalon.rectangle(rowcol(0,12),rowcol(15,15)) = 222;
-
- assert( test_im == test_im_ethalon );
- }
-
- #if 0
- {
- cout << "\tTest equalizing of uneven histogram\n";
- IMAGE test_im(16,16,4);
- test_im = 8; // Make a stripy image
- register int i,j; // with very uneven histogram
- for(i=0; i<8; i++) // (large peak at value 8)
- for(j=0; j<16; j++)
- test_im(i,j) = j;
-
- test_im.print("before");
- test_im.equalize(16);
- test_im.print("after");
- }
- #endif
-
- cout << "\nDone\n\n";
- }
-
-
- // Test expand/shrink operations
- static void test_expand_shrink()
- {
- const int pattern = 154;
-
- cout << "\n\nTest shrink/expand image operations\n";
-
- {
- cout << "\tExpansion/shrinking of the uniform image\n";
- Test_image = pattern;
- IMAGE blown_out(IMAGE::Expand,Test_image);
- assert( blown_out.q_nrows() == 2*Test_image.q_nrows() );
- assert( blown_out.q_ncols() == 2*Test_image.q_ncols() );
- assert( blown_out.q_depth() == Test_image.q_depth() );
- assert( blown_out == pattern );
- IMAGE blown_shrunk(IMAGE::Shrink,blown_out);
- assert( blown_shrunk == Test_image );
-
- {
- IMAGE im(Test_image);
- im.coerce(Test_image);
- assert( im == Test_image );
- }
-
- {
- IMAGE im(Test_image.q_nrows()+1,Test_image.q_ncols()/2-1,
- Test_image.q_depth());
- im.coerce(Test_image);
- verify_pixel_value(im,pattern);
- }
-
- {
- IMAGE im(Test_image.q_nrows()/3,Test_image.q_ncols()*2,
- Test_image.q_depth());
- im.coerce(Test_image);
- verify_pixel_value(im,pattern);
- }
-
- }
-
- {
- cout << "\tExpansion of the uniform image with a small stain\n";
- Test_image = pattern;
- Test_image(0,0) = 1;
- Test_image(1,1) = 0;
- IMAGE blown_out(IMAGE::Expand,Test_image);
- assert( blown_out(1,1) == 1 );
- assert( blown_out(3,3) == 0 );
- class BlowImage : public LazyImage
- {
- const IMAGE& orig_image;
- void fill_in(IMAGE& im) const
- {
- for(register int i=0; i<im.q_nrows(); i++)
- for(register int j=0; j<im.q_ncols(); j++)
- im(i,j) = orig_image(i/2,j/2);
- }
- public:
- BlowImage(const IMAGE& image) :
- LazyImage(2*image.q_nrows(),2*image.q_ncols(),image.q_depth()),
- orig_image(image) {}
- };
- IMAGE another_blown_out = BlowImage(Test_image);
- assert( another_blown_out == blown_out );
- IMAGE yet_another_blown_out(another_blown_out);
- yet_another_blown_out.clear();
- yet_another_blown_out.coerce(Test_image);
- assert( yet_another_blown_out == blown_out );
- IMAGE blown_shrunk(IMAGE::Shrink,blown_out);
- assert( blown_shrunk == Test_image );
- blown_out.square_of(2,rowcol(0,0)) += pattern - 1;
- blown_out.square_of(2,rowcol(2,2)) += pattern;
- assert( blown_out == pattern );
- }
- {
- cout << "\tShrinking the uniform image with small stains\n";
- Test_image = pattern;
- Test_image.square_of(2,rowcol(0,0)) = 1; Test_image(0,0) = 0;
- Test_image.square_of(2,rowcol(2,0)) = 5; Test_image(3,1) = 0;
- Test_image.square_of(2,rowcol(0,2)) = 0; Test_image(0,2) = 1;
- Test_image.square_of(2,rowcol(0,4)) = 0; Test_image(1,5) = 7;
- Test_image.square_of(2,rowcol(2,2)) = 1;
- Test_image(2,2) = 0; Test_image(3,3) = 0;
-
- IMAGE shrunk(IMAGE::Shrink,Test_image);
- assert( shrunk(0,0) == 1 );
- assert( shrunk(0,1) == 0 );
- shrunk(0,0) += pattern - 1;
- shrunk(1,0) += pattern - 4;
- shrunk(0,1) += pattern;
- shrunk(0,2) += pattern - 2;
- shrunk(1,1) += pattern - 1;
- assert( shrunk == pattern );
- }
- {
- cout << "\tStretching/shrinking an image with vertical stripes\n";
- class MakeVStripes : public PixelAction
- {
- GRAY pattern;
- void operation(GRAY& pixel) { pixel = col & 1 ? pattern : 0; }
- public: MakeVStripes(const GRAY _p) : pattern(_p) {}
- };
- Test_image.apply(MakeVStripes(pattern));
- IMAGE shrunk(Test_image.q_nrows()/3+1,
- Test_image.q_ncols()/2,Test_image.q_depth());
- shrunk.coerce(Test_image);
- verify_pixel_value(shrunk,pattern);
- IMAGE vert_shrunk(Test_image.q_nrows()/3-1,
- Test_image.q_ncols(),Test_image.q_depth());
- vert_shrunk.coerce(Test_image);
- assert( Test_image.rectangle(rowcol(0,0),
- rowcol(Test_image.q_nrows()/3-2,
- Test_image.q_ncols()-1))
- == vert_shrunk );
- IMAGE vert_stretched(Test_image.q_nrows()+7,
- Test_image.q_ncols(),Test_image.q_depth());
- vert_stretched.coerce(Test_image);
- assert( vert_stretched.rectangle(rowcol(0,0),
- rowcol(Test_image.q_nrows()-1,
- Test_image.q_ncols()-1))
- == Test_image );
- }
-
- {
- cout << "\tStretching/shrinking an image with horizontal stripes\n";
- class MakeHStripes : public PixelAction
- {
- GRAY pattern;
- void operation(GRAY& pixel) { pixel = row & 1 ? pattern : 0; }
- public: MakeHStripes(const GRAY _p) : pattern(_p) {}
- };
- Test_image.apply(MakeHStripes(pattern));
- IMAGE shrunk(Test_image.q_nrows()/2,
- Test_image.q_ncols()+7,Test_image.q_depth());
- shrunk.coerce(Test_image);
- verify_pixel_value(shrunk,pattern);
- IMAGE hor_shrunk(Test_image.q_nrows(),
- Test_image.q_ncols()/3-1,Test_image.q_depth());
- hor_shrunk.coerce(Test_image);
- assert( Test_image.rectangle(rowcol(0,0),
- rowcol(Test_image.q_nrows()-1,
- Test_image.q_ncols()/3-2))
- == hor_shrunk );
- IMAGE hor_stretched(Test_image.q_nrows(),
- Test_image.q_ncols()+9,Test_image.q_depth());
- hor_stretched.coerce(Test_image);
- assert( hor_stretched.rectangle(rowcol(0,0),
- rowcol(Test_image.q_nrows()-1,
- Test_image.q_ncols()-1))
- == Test_image );
- }
-
- cout << "\nDone\n";
- }
-
- /*
- *------------------------------------------------------------------------
- * The testing routing module
- */
-
- main()
- {
- test_primitive();
- test_rowcol();
- test_pixel_op();
- test_image_op();
-
- test_scalar_product();
- test_image_norms();
- test_image_extrema();
-
- test_equalization();
- test_expand_shrink();
- }
-
-